package entity

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"l_net/erro"
	"l_net/pkg/file"
	"l_net/pkg/server"
	"net"
)

type TcpListener struct {
	Name             string         `json:"name"`
	Dir              string         `json:"dir"`
	Port             string         `json:"port"`
	IsMoniter        bool           `json:"isMoniter"`
	IsShared         bool           `json:"isShared"`
	SharedConfigPath string         `json:"sharedConfigPath"`
	HostList         []file.HostObj `json:"hostList"`
	Exclude          []file.HostObj `json:"exclude"`
	ExcludeMap       map[string]struct{}
}

func NewTcpListener(path string) *TcpListener {
	t := &TcpListener{
		Exclude:   nil,
		IsMoniter: true,
		IsShared:  false,
		Dir:       "./",
	}
	// 读取 JSON 文件
	data, err := ioutil.ReadFile(path)
	if err != nil {
		fmt.Println("读取文件失败:", err)
		return nil
	}

	// 解析 JSON 数组到 Person 切片
	err = json.Unmarshal(data, &t)
	if err != nil {
		fmt.Println("解析 JSON 失败:", err)
		return nil
	}
	//将Exclude输入装入map中
	t.ExcludeMap = make(map[string]struct{})
	for _, v := range t.Exclude {
		t.ExcludeMap[v.IP] = struct{}{}
	}
	return t
}

// 开始启动tcp监听，监听的端口号和共享目录的地址
func (t *TcpListener) Start() {

	addr := "0.0.0.0:" + t.Port
	tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
	erro.NetErrShow(err)

	listener, err := net.ListenTCP("tcp", tcpAddr)
	erro.NetErrShow(err)

	var w *file.Watch = nil
	if t.IsMoniter {
		fmt.Print("开始监听")
		w = file.NewWatch(&t.HostList)
		w.WatchDir(t.Dir)
	}
	if t.IsShared {
		fmt.Print("开始共享")
		s := NewWebServe(t.SharedConfigPath)
		s.HostList = t.HostList
		go s.Start()
	}

	for {
		acceptTCP, err := listener.AcceptTCP()
		erro.NetErrShowTcp(err)

		fmt.Println("start a TCP connection:", acceptTCP.RemoteAddr())
		ip, _, _ := net.SplitHostPort(acceptTCP.RemoteAddr().String())
		_, ok := t.ExcludeMap[ip]
		//如果存在就拦截IP
		if ok {
			acceptTCP.Close()
			continue
		}
		tcpCon := server.NewTcp(acceptTCP)
		srv := file.NewServer(tcpCon, t.Dir, w)
		go srv.Start()
		// fmt.Println("end a connection:", acceptTCP.RemoteAddr())
	}
}
